package com.bj58.ecdata.calc.dbservice.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Tuple;

import com.bj58.ecdata.calc.dbservice.consts.Constant;
import com.bj58.ecdata.calc.dbservice.dao.SearchWordDao;
import com.bj58.ecdata.calc.dbservice.dao.TrackDao;
import com.bj58.ecdata.calc.dbservice.dao.TrackUVDao;
import com.bj58.ecdata.calc.dbservice.dao.model.DataPoint;
import com.bj58.ecdata.calc.dbservice.dao.model.SearchWord;
import com.bj58.ecdata.calc.dbservice.dao.model.TrackModel;
import com.bj58.ecdata.calc.dbservice.load.SpringUtils;
import com.bj58.ecdata.calc.dbservice.model.ResultObj;
import com.bj58.ecdata.calc.dbservice.model.TrackResultData;
import com.bj58.ecdata.calc.dbservice.service.BusslineEnum;
import com.bj58.ecdata.calc.dbservice.service.PlatformEnum;
import com.bj58.ecdata.calc.dbservice.service.TrackService;
import com.bj58.ecdata.util.DateUtils;
import com.bj58.ecdata.util.JsonUtils;
import com.bj58.spat.scf.server.contract.annotation.ServiceBehavior;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * @author lichao
 *
 */
@ServiceBehavior
public class TrackServiceImpl extends BaseServiceImpl implements TrackService {

	public TrackServiceImpl() {
		super(Lists.newArrayList("pv", "listpv", "vppv", "uv"));
	}

	private TrackDao dao = SpringUtils.getInstance().getBean(TrackDao.class);
	private TrackUVDao uvDao = SpringUtils.getInstance().getBean(TrackUVDao.class);
	private SearchWordDao searchWordDao = SpringUtils.getInstance().getBean(SearchWordDao.class);

	@Override
	public String getDailySum(PlatformEnum platform, BusslineEnum bussline) {
		TrackModel model = new TrackModel();
		model.setTime(DateUtils.getTruncatedToday());
		model.setPlatform(platform != null ? platform.value() : null);
		model.setBussline(bussline != null ? bussline.value() : null);

		long pv = dao.loadDailySum("pv", model);
		long vppv = dao.loadDailySum("vppv", model);

		TrackModel data = new TrackModel();
		data.setPv(pv);
		data.setVppv(vppv);
		data.setTime(dao.getLatest());
		return JsonUtils.toJson(data);
	}

	@Override
	public String getData(String type, PlatformEnum platform, BusslineEnum bussline, long time) {

		checkType(type);

		long endTime = dao.getLatest();
		List<TrackModel> params = createModels(time, endTime, Constant._2s, Constant._1h, platform, bussline);
		List<DataPoint> datas = dao.load(type, params, false);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	@Override
	public String getDataTodayMinute(String type, long time) {

		checkType(type);

		long zeroTime = DateUtils.getTruncatedToday();
		long curTime = dao.getLatest();
		long endTime = DateUtils.truncateToMinute(curTime) - Constant._1m;
		List<TrackModel> params = createModels(time, endTime, Constant._1m, endTime - zeroTime + Constant._1m, null, null);
		List<DataPoint> datas = dao.loadMinute(type, params, false);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);

	}


	@Override
	public String getYesTodayMinute(String type) {

		checkType(type);

		long zeroTime = DateUtils.getTruncatedToday();
		List<TrackModel> params = createModels(0, zeroTime, Constant._1m, Constant._1d, null, null);
		List<DataPoint> datas = dao.loadMinute(type, params, false);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);

	}
	
	@Override
	public String getDataTodayHourly(String type, PlatformEnum platform, BusslineEnum bussline) {

		checkType(type);

		long zeroTime = DateUtils.getTruncatedToday();
		long curTime = dao.getLatest();
		long endTime = DateUtils.truncateToHour(curTime) - Constant._1h;
		List<TrackModel> params = createModels(0, endTime, Constant._1h, endTime - zeroTime + Constant._1h, platform, bussline);
		List<DataPoint> datas = dao.loadHourly(type, params, false);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	@Override
	public String getDataYesterdayHourly(String type, PlatformEnum platform, BusslineEnum bussline) {

		checkType(type);

		long endTime = DateUtils.getTruncatedToday() - Constant._1h;
		List<TrackModel> params = createModels(0, endTime, Constant._1h, Constant._1d, platform, bussline);
		List<DataPoint> datas = dao.loadHourly(type, params, false);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	private List<TrackModel> createModels(long startTime, long endTime, long interval, long span, PlatformEnum platform, BusslineEnum bussline) {
		long minTime = endTime - span;
		if (startTime == 0 || startTime < minTime) {
			startTime = minTime;
		}

		List<TrackModel> models = Lists.newArrayList();
		for (long i = startTime + interval; i <= endTime; i += interval) {

			TrackModel model = new TrackModel();
			model.setTime(i);
			model.setPlatform(platform != null ? platform.value() : null);
			model.setBussline(bussline != null ? bussline.value() : null);
			models.add(model);
		}
		return models;
	}

	@Override
	public String getSearchWrodTopList(PlatformEnum platform, BusslineEnum bussline, int count) {
		if (count < 1) {
			count = 1;
		}
		SearchWord model = new SearchWord();
		model.setTime(DateUtils.getTruncatedToday());
		model.setPlatform(platform != null ? platform.value() : null);
		model.setBussline(bussline != null ? bussline.value() : null);
		Set<Tuple> tuples = searchWordDao.loadSearchWordList(model, count);
		List<TrackResultData> datas = Lists.newArrayList();
		for (Tuple tuple : tuples) {
			TrackResultData data = new TrackResultData();
			data.setSearchWord(tuple.getElement());
			data.setValue((long) tuple.getScore());
			datas.add(data);
		}
		ResultObj result = new ResultObj();
		result.setData(datas);
		return JsonUtils.toJson(result);
	}

	
	

	@Override
	public String getUVDataTodayMinute(long time, PlatformEnum platform) {
		long zeroTime = DateUtils.getTruncatedToday();
		long endTime = uvDao.getLatest();
		time = DateUtils.truncateToMinute(time);
		List<TrackModel> params = createModels(time - Constant._1m, endTime, Constant._1m, endTime - zeroTime + Constant._1m, platform, null);
		List<DataPoint> datas = uvDao.loadMinute(params);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);

	}

	@Override
	public String getUVYesTodayMinute(PlatformEnum platform) {
		long zeroTime = DateUtils.getTruncatedToday()-Constant._1m;
		List<TrackModel> params = createModels(zeroTime-Constant._1d, zeroTime, Constant._1m, Constant._1d, platform, null);
		List<DataPoint> datas = uvDao.loadMinute(params);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);

	}
	
	@Override
	public String getUVData(PlatformEnum platform, long time) {
		long endTime = uvDao.getLatest();
		time = DateUtils.truncateToMinute(time);
		List<TrackModel> params = createModels(time - Constant._1m, endTime, Constant._1m, Constant._1h, platform, null);
		List<DataPoint> datas = uvDao.loadMinute(params);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		return JsonUtils.toJson(result);
	}

	@Override
	public String getAllUV() {
		long endTime = uvDao.getLatest();
		long minTime = DateUtils.truncateToMinute(uvDao.getLatest());		
		List<TrackModel> params = createModels(minTime - Constant._1m, minTime, Constant._1m, Constant._1h, null, null);
		List<DataPoint> datas = uvDao.loadMinute(params);
		Map<String, Object> result = Maps.newHashMap();
		result.put("data", datas);
		result.put("time", endTime);
		return JsonUtils.toJson(result);
	}
}
